package nl.infodation.emr.utility;

import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import nl.infodation.emr.pricingservice.controller.ControllerFactory;
import nl.infodation.emr.pricingservice.entity.LanguageSystem;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.peholmst.i18n4vaadin.I18N;
import com.github.peholmst.i18n4vaadin.ResourceBundleI18N;
import com.github.peholmst.i18n4vaadin.support.I18NComponentSupport;
import com.vaadin.data.Property;
import com.vaadin.data.util.BeanItem;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.Select;

@SuppressWarnings("rawtypes")
public final class I18NPricingLangSupport {
	/**
	 * 
	 */
	private static Locale currentLocale = null;
	private static I18NComponentSupport support;
	private static Select selectBox;
	private static final Logger LOG = LoggerFactory.getLogger(I18NPricingLangSupport.class);
	
	/** A private Constructor prevents any other class from instantiating. */
	private I18NPricingLangSupport() {
		//	 Optional 
	}
	
	public static Select getSelectBox(){
		selectBox= new Select();
		selectBox.setNullSelectionAllowed(false);
		selectBox.setImmediate(true);
		List<BeanItem> beans = ControllerFactory.getLanguageSystemController().getPaginationList(1, Integer.MAX_VALUE);
		
		for (BeanItem item : beans) {
			LanguageSystem languageSystem = (LanguageSystem)item.getBean();
			selectBox.addItem(languageSystem.getLanguageSystemId());
			selectBox.setItemCaption(languageSystem.getLanguageSystemId(), languageSystem.getDescription());
		}
		
		return selectBox;
	}
	
	public void setI18N(final I18N i18n) {
		synchronized (support) {
			 support.setI18N(i18n);
		}
	}

	public I18N getI18N() {
		synchronized (support) {
			if (support.getI18N() == null) {
				final I18N i18n = new ResourceBundleI18N("messages", Locale.ENGLISH, Locale.FRENCH);
				support.setI18N(i18n);
			}
		}
		return support.getI18N();
	}
	
	public static void setCurrentLang(final Locale locale) {
		currentLocale = locale;
	}

	public static Locale getCurrentLang() {
			if (currentLocale == null) {
				currentLocale = Locale.ENGLISH;
		}
		return currentLocale;
	}
	
	public Locale switchLocale(final Locale locale) {
		return null;
	}
	
	public Object clone() throws CloneNotSupportedException {
		throw new CloneNotSupportedException();
	}
	
	public static void localeChanged(final I18N sender, final Locale oldLocale, final Locale newLocale, Iterator<Component> components) {
		LOG.debug("Locale change detected from {} to {}", oldLocale, newLocale);
		if (newLocale == null) {
			return;
		}
		
		if (newLocale.equals(oldLocale)) {
			LOG.warn("Strange locale change detected, ignoring"); // probably a programming mistake somewhere
			return;
		}
		
		while (components.hasNext()) {
			changeLocale(components.next(), sender, newLocale);
		}
		LOG.debug("Locale changed in components from {} to {}", oldLocale, newLocale);
	}
	
	private static void changeLocale(final Component component, final I18N sender, final Locale newLocale) {
		LOG.debug("Changing locale for {}", component);
		final Locale locale = component.getLocale();
		if (!newLocale.equals(locale)) { // works because of constants in Locale.
			final String key = component.getDebugId();
			if (key != null) {
				LOG.debug("Looking for {} in locale {}", key, newLocale);
				final String newCaption = sender.getMessage(key);
				if (newCaption.length() > 0) {
					component.setCaption(newCaption);
				}

				if (component instanceof AbstractComponent) { 
					final String key_desc = key + "_desc";
					final String newDesc = sender.getMessage(key_desc);
					if (newDesc.length() > 0) {
						final AbstractComponent abstractComponent = (AbstractComponent)component;
						abstractComponent.setDescription(newDesc);
					}
				}

				if (component instanceof Property) {
					final String key_value = key + "_value";
					final String newValue = sender.getMessage(key_value);
					if (newValue.length() > 0) {
						final Property property = (Property) component;
						property.setValue(newValue);
					}
				}
			}
			if (component instanceof ComponentContainer) {
				final ComponentContainer cpntContainer = (ComponentContainer)component;
				final Iterator<Component> components = cpntContainer.getComponentIterator();
				while (components.hasNext()) {
					changeLocale(components.next(), sender, newLocale);
				}
			}
		} else {
			LOG.debug("Strange locale switch detected, ignoring.");
		}
	}
	
}
